const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
const WorkboxWebpackPlugin = require('workbox-webpack-plugin')
    // 设置nodejs环境变量 注释掉就默认走production了，和webpack.config.js的mode属性无关
    // process.env.NODE_ENV='development';
module.exports = {
    entry: './src/index.js',
    // 多入口
    // entry: {index:'./src/index.js',index2:'./src/index2.js'},
    output: {
        // 多入口
        // filename: 'js/[name].[contenthash:6].js',
        // 单入口
        filename: 'js/index3.[contenthash:6].js',
        path: resolve(__dirname, 'build')
    },
    module: {
        rules: [{
                test: /\.js$/,
                exclude: /node_modules/,

                // 有use就不要loader了，一个是字符串数组，一个是字符串。use其实就是一个loader数组
                use: [
                    /* 开启多进程打包
                    进程启动大约0.6s,进程之间的通信也有开销
                    js文件很多，消耗时间很长，就需要这个，否则，得不偿失。先加载babel-loader，再加载thread-loader */
                    {
                        loader: 'thread-loader',
                        options: {
                            // 进程数量
                            workers: 7
                        }
                    }, {
                        loader: 'babel-loader',
                        options: {
                            // 指示babel要做什么样的兼容性处理
                            presets: [
                                ['@babel/preset-env',
                                    {
                                        // 按需加载
                                        useBuiltIns: 'usage',
                                        // 指定core-js版本
                                        corejs: {
                                            version: 3
                                        },
                                        // 指定兼容性做到哪个版本的浏览器
                                        targets: {
                                            chrome: '60',
                                            firefox: '60',
                                            ie: '9',
                                            safari: '10',
                                            edge: '17'
                                        }
                                    }
                                ]
                            ]
                        },
                    }
                ],
            }, {
                test: /\.css$/,
                use: [
                    // 'style-loader', 
                    // 这个loader替代style-loader。作用：把js中的css打包成为单独的文件
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    {
                        loader: 'postcss-loader',
                        // 在postcss.config.js写了配置，所以option里面注释掉了
                        /* options:{
                            ident:'postcss',
                            plugins:()=>[require('postcss-preset'-env)()]
                        } */
                    }
                ],
            }, {
                test: /\.less$/,
                // 使用哪些loader
                // 使用这些loader前我们一般都会在项目最外层下载这些依赖。因为npm会一层一层往上面找。所以我们就放在最外面一层 npm i webpack webpack-cli -D
                // npm i css-loader style-loader -D
                use: [
                    //use数组中loader执行的顺序：从右到左，从上到下，依次执行
                    // 创建了style标签，将js中的样式资源插入进行，添加到head中
                    'style-loader',
                    // 将css文件编译成commonjs模块加载到js中，里面内容是样式字符串
                    'css-loader',
                    'less-loader'
                ]
            },
            // eslint校准
            /* {
                test: /\.js$/,
                // 一定要排除掉node_modules
                exclude: /node_modules/,
                loader: 'eslint-loader',
                options: {
                    // 为false的话就需要自己手动校准
                    fix: true
                }
            }, */
            {
                test: /\.(jpg|png|gif)$/,
                // 下载url-loader file-loader
                loader: 'url-loader',
                options: {
                    // 图片大小小于8kb就会被base64处理
                    // 优点：减少请求数量，减轻服务器压力
                    // 缺点：图片体积会更大（文件请求速度更慢）
                    limit: 8 * 1024,
                    // 遇到的bug:url-loader默认用es6模块化解析，而html-loader引入图片是commonjs引入
                    // 解析时候Img src就是引入了[Object module]
                    // 解决方法关闭url-loader的es6模块化，使用commonjs解析
                    esModule: false,
                    // 给图片的哈希名字进行压缩
                    name: '[hash:10].[ext]'
                }
            }, {
                test: /\.html$/,
                // 处理html文件的img图片（负责引入img，从而能够被url-loader解析处理
                loader: 'html-loader'
            }, {
                // 我们不单单可以用test也可以用exclude排除哪些文件
                //{ test: /\.css$/, loader: 'style!css' },其他写法1、"-loader"其实是可以省略不写的，多个loader之间用“!”连接起来。
                exclude: /\.(css|js|html|less|jpg|png|gif)/,
                loader: 'file-loader',
                options: { name: '[hash:10].[ext]' }
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            // 默认就会引入打包后的js文件
            // 决定了模仿哪个页面结构
            template: './src/index.html',
            minify: {
                // 是否移除空格
                collapseWhitespace: true,
                // 是否移除注释
                removeComments: true
            }
        }),
        new MiniCssExtractPlugin({
            // 对输出的css文件重命名
            filename: 'css/built.css'
        }),
        new OptimizeCssAssetsWebpackPlugin(),
        new WorkboxWebpackPlugin.GenerateSW({
            /* 
            1.帮助serviceworker快速启动
            2.删除旧的serviceworker
            生成一个serviceworker配置文件
            */
            clientsClaim: true,
            skipWaiting: true
        }),
    ],
    optimization: {
        // node_modules里面的文件单独打包成一个js
        splitChunks: {
            chunks: 'all'
        }
    },
    // mode: 'development',
    mode: 'production',
    externals: {
        // 拒绝jquery被打包 Npm包名
        jquery: 'jQuery'
    },
    // 特点：只会在内存中编译打包。不会有任何输出
    // 启动devServer指令：npx webpack-dev-server
    devServer: {
        contentBase: resolve(__dirname, 'build'),
        // 启用gzip压缩
        comporess: true,
        // 端口号
        port: 10,
    }
}